import logging
import observable
import constants
import math
import pygame
import os
import data
import random

class WorldObject(pygame.sprite.Sprite, observable.Observable):
    """Understands any object inside the world where the user is playing"""

    def __init__(self, x=30, y=30, speed=0, angle=0):
        pygame.sprite.Sprite.__init__(self)
        observable.Observable.__init__(self)
        self.sprites = []
        self.image = None
        self.rect = None
        self.speed = speed
        self.x = x
        self.y = y
        self._dead = False
        self._angle = angle
        self.z_index = 5
        self.decorations = []
        self._scrollable = True
        self._collision_list = []

    @staticmethod
    def cmp_z_index(char1, char2):
        if char1.z_index < char2.z_index:
            return -1
        elif char1.z_index == char2.z_index:
            return 0
        return 1

    def set_scrollable(self, bool):
        self._scrollable = bool

    def get_decorations(self):
        return self.decorations

    def change_to_random_sprite(self):
        new_sprite = random.Random().randint(0, len(self.sprites) -1)
        self.change_to_sprite(new_sprite)

    def change_to_sprite(self, idx):
        self.image = self.sprites[idx]

    def get_rectangle(self):
        left, top = self.position()
        rect = self.image.get_rect(top=top, left=left)
        return rect

    def update(self): #Sprite hook
        self.rect = self.get_rectangle()

    def die(self):
        logging.getLogger(constants.LOGGER_NAME).debug('%s died' % (self))
        self._dead = True

    def is_dead(self):
        return self._dead
        
    def position(self):
        return (self.x, self.y)

    def surface(self):
        return self.image

    def __str__(self):
        return "(x=%s, y=%s)" % (self.x, self.y)
    
    def next_position(self):
        newx = self.x + self.calculate_coordinate(math.cos)
        newy = self.y - self.calculate_coordinate(math.sin)
        return (newx, newy)

    def tick_update(self):
        self.x, self.y = self.next_position()

    def calculate_coordinate(self, cos_or_sin):
        return self.speed * cos_or_sin(math.radians(self._angle))

    def set_position(self, x, y):
        self.x = x
        self.y = y

    def overlaps(self, other):
        if self.image and other.image:
            this_rect = self.get_rectangle()
            other_rect = other.get_rectangle()

            return this_rect.colliderect(other_rect)

        return False

    def should_scroll_down(self):
        return self._scrollable

    def scroll_down(self):
        self.y += constants.VERTICAL_SCROLL_FACTOR
    
    def collide(self, other):
        #logging.getLogger(constants.LOGGER_NAME).debug('%s collided with %s' % (self, other))
        pass

    def collision_list(self):
        return self._collision_list

    def before_collisions(self):
        pass

    def add_to_collision_list(self, obj):
        self._collision_list.append(obj)

    def empty_collision_list(self):
        self._collision_list = []
    
    def load_sprites(self, paths):
        for path in paths:
            self.sprites.append(data.load_image(path, True))
